package com.wnxy.admin.common.log;

import com.wnxy.admin.common.handler.Asserts;
import com.wnxy.admin.common.handler.BusinessEnum;
import com.wnxy.admin.common.util.TokenUtil;
import com.wnxy.admin.entity.Logentry;
import com.wnxy.admin.entity.Staff;
import com.wnxy.admin.service.ILogentryService;
import com.wnxy.admin.service.IStaffService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

@Aspect
@Component
public class LogAspect {

    private final ILogentryService logentryServiceImpl;
    private final IStaffService staffServiceImpl;

    public LogAspect(ILogentryService logentryServiceImpl, IStaffService staffServiceImpl) {
        this.logentryServiceImpl = logentryServiceImpl;
        this.staffServiceImpl = staffServiceImpl;
    }

    // 使用@annotation来匹配带有自定义注解的方法
    @Pointcut("@annotation(com.wnxy.admin.common.log.Loggable)")
    public void loggableMethods() {
    }

    @Before("loggableMethods()")
    public void logBefore(JoinPoint joinPoint) {
        // 在方法执行前记录额外信息，如果需要的话
    }

    @After("loggableMethods()")
    public void logAfter(JoinPoint joinPoint) {
        // 在方法执行后记录额外信息，如果需要的话
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String token = request.getHeader("Authorization");
        Asserts.fail(!StringUtils.hasLength(token), BusinessEnum.TOKEN_IS_NULL);
        Integer staffId = Integer.valueOf(TokenUtil.getPayLoad(token.replace("Bearer", ""), "staffId"));
        Staff staff = staffServiceImpl.getById(staffId);
        String name = staff.getName();

        // 获取操作日期
        Date operationDate = new Date();

        // 获取IP地址
        String ipAddress = LocalIPUtil.getLocalIpAddress(); // 自定义方法获取IP地址

        // 获取被操作的方法
        String methodName = joinPoint.getSignature().toShortString();

        // 在这里将日志信息存储到日志系统或数据库中
        Logentry logEntry = new Logentry(null, name, operationDate, ipAddress, methodName);
        // 使用日志服务将logEntry保存到数据库或写入日志文件
        logentryServiceImpl.save(logEntry);
    }
}